#include "stdafx.h"
#include "AccelBase.h"

#include <gtl/string/split.h>
#include <gtl/string/string.h>

CAccelBase::CAccelBase(void)
{
}

CAccelBase::~CAccelBase(void)
{
}

static struct tagKeyName
{
	CString strDesc;
	WORD key;
}KeyName[] =
{
	_T("Left mouse button"),		VK_LBUTTON,
	_T("Right mouse button"),		VK_RBUTTON,
	_T("Control-break processing"),	VK_CANCEL,
	_T("Middle mouse button"),		VK_MBUTTON,
	_T("Back Space"),				VK_BACK,
	_T("Tab"),						VK_TAB,
	_T("Clear"),					VK_CLEAR,
	_T("Enter"),					VK_RETURN,
	_T("Shift"),					VK_SHIFT,
	_T("Ctrl"),						VK_CONTROL,
	_T("Alt"),						VK_MENU,
	_T("Pause"),					VK_PAUSE,
	_T("Caps Lock"),				VK_CAPITAL,
	_T("Esc"),						VK_ESCAPE,
	_T("Space"),					VK_SPACE,
	_T("Page Up"),					VK_PRIOR, 
	_T("Page Down"),				VK_NEXT,
	_T("End"),						VK_END,
	_T("Home"),						VK_HOME,
	_T("Left"),						VK_LEFT,
	_T("Up"),						VK_UP,
	_T("Right"),					VK_RIGHT,
	_T("Down"),						VK_DOWN,
	_T("Select"),					VK_SELECT,
	_T("Excute"),					VK_EXECUTE,
	_T("Print Screen"),				VK_SNAPSHOT,
	_T("Insert"),					VK_INSERT,
	_T("Delete"),					VK_DELETE,
	_T("Help"),						VK_HELP,
	_T("0"),						'0',
	_T("1"),						'1',
	_T("2"),						'2',
	_T("3"),						'3',
	_T("4"),						'4',
	_T("5"),						'5',
	_T("6"),						'6',
	_T("7"),						'7',
	_T("8"),						'8',
	_T("9"),						'9',
	_T("A"),						'A',
	_T("B"),						'B',
	_T("C"),						'C',
	_T("D"),						'D',
	_T("E"),						'E',
	_T("F"),						'F',
	_T("G"),						'G',
	_T("H"),						'H',
	_T("I"),						'I',
	_T("J"),						'J',
	_T("K"),						'K',
	_T("L"),						'L',
	_T("M"),						'M',
	_T("N"),						'N',
	_T("O"),						'O',
	_T("P"),						'P',
	_T("Q"),						'Q',
	_T("R"),						'R',
	_T("S"),						'S',
	_T("T"),						'T',
	_T("U"),						'U',
	_T("V"),						'V',
	_T("W"),						'W',
	_T("X"),						'X',
	_T("Y"),						'Y',
	_T("Z"),						'Z',
	_T("Left windows"),				VK_LWIN,
	_T("Right windows"),			VK_RWIN,
	_T("Applications"),				VK_APPS,
	_T("Numeric keypad 0"),			VK_NUMPAD0,
	_T("Numeric keypad 1"), 		VK_NUMPAD1,
	_T("Numeric keypad 2"), 		VK_NUMPAD2,
	_T("Numeric keypad 3"), 		VK_NUMPAD3,
	_T("Numeric keypad 4"), 		VK_NUMPAD4,
	_T("Numeric keypad 5"), 		VK_NUMPAD5,
	_T("Numeric keypad 6"), 		VK_NUMPAD6,
	_T("Numeric keypad 7"), 		VK_NUMPAD7,
	_T("Numeric keypad 8"), 		VK_NUMPAD8,
	_T("Numeric keypad 9"),			VK_NUMPAD9,
	_T("Multiply"),					VK_MULTIPLY,
	_T("Add"),						VK_ADD,
	_T("Separator"),				VK_SEPARATOR,
	_T("Subtract"),					VK_SUBTRACT,
	_T("Decimal Point"),			VK_DECIMAL,
	_T("Divide"),					VK_DIVIDE,
	_T("F1"),						VK_F1,
	_T("F2"),						VK_F2,
	_T("F3"),						VK_F3,
	_T("F4"),						VK_F4,
	_T("F5"),						VK_F5,
	_T("F6"),						VK_F6,
	_T("F7"),						VK_F7,
	_T("F8"),						VK_F8,
	_T("F9"),						VK_F9,
	_T("F10"),						VK_F10,
	_T("F11"),						VK_F11,
	_T("F12"),						VK_F12,
	_T("F13"),						VK_F13,
	_T("F14"),						VK_F14,
	_T("F15"),						VK_F15,
	_T("F16"),						VK_F16,
	_T("F17"),						VK_F17,
	_T("F18"),						VK_F18,
	_T("F19"),						VK_F19,
	_T("F20"),						VK_F20,
	_T("F21"),						VK_F21,
	_T("F22"),						VK_F22,
	_T("F23"),						VK_F23,
	_T("F24"),						VK_F24,
	_T("Attn"),						VK_ATTN,
	_T("CrSel"),					VK_CRSEL,
	_T("ExSel"),					VK_EXSEL,
	_T("Erase"),					VK_EREOF,
	_T("Play"),						VK_PLAY,
	_T("Zoom"),						VK_ZOOM,
	_T("Reserved for future use"),	VK_NONAME,
	_T("PA1"),						VK_PA1,
	_T("Clear(OEM)"),				VK_OEM_CLEAR,

	_T("\\"),						'\\',
	_T("-"),						'-',
	_T("="),						'=',
	_T("["),						'[',
	_T("]"),						']',
	_T(";"),						';',
	_T("\'"),						'\'',
	_T(","),						',',
	_T("."),						'.',
	_T("/"),						'/',
	_T("`"),						'`'
};

CString CAccelBase::GetKey(WORD wKey)
{
	for(int i = 0; i < sizeof(KeyName) / sizeof(tagKeyName); ++i)
	{
		if(KeyName[i].key == wKey)
			return KeyName[i].strDesc;
	}

	return _T("");
}

CString CAccelBase::GetVirtKey(WORD wVirtKey)
{
	CString strVirtKey;

	if(wVirtKey & FCONTROL)
		strVirtKey += _T("Ctrl");
	if(wVirtKey & FSHIFT)
		strVirtKey += strVirtKey.IsEmpty() ? _T("Shift") : _T("+Shift");
	if(wVirtKey & FALT)
		strVirtKey += strVirtKey.IsEmpty() ? _T("Alt") : _T("+Alt");

	return strVirtKey;
}

WORD CAccelBase::GetKey(LPCTSTR lpszKeyDesc)
{
	if(lpszKeyDesc == NULL)
		return 0;

	for(int i = 0; i < sizeof(KeyName) / sizeof(tagKeyName); ++i)
	{
		if(KeyName[i].strDesc.CompareNoCase(lpszKeyDesc) == 0)
			return KeyName[i].key;
	}

	return 0;
}

WORD CAccelBase::GetVirtKey(LPCTSTR lpszVirtKeys)
{
	std::vector<gtl::tstring> vecVirtKey;
	gtl::string::split(vecVirtKey, lpszVirtKeys, _T("+"));
	WORD wVirtKey = FVIRTKEY;
	for(size_t j = 0; j < vecVirtKey.size(); ++j)
	{
		if(gtl::string::equal(vecVirtKey[j], _T("ctrl")))
			wVirtKey |= FCONTROL;
		else if(gtl::string::equal(vecVirtKey[j], _T("alt")))
			wVirtKey |= FALT;
		else if(gtl::string::equal(vecVirtKey[j], _T("shift")))
			wVirtKey |= FSHIFT;
	}

	return wVirtKey;
}

WORD CAccelBase::GetVirtKey(bool bCtrl, bool bShift, bool bAlt)
{
	WORD wVirtKey = FVIRTKEY;
	if(bCtrl)
		wVirtKey |= FCONTROL;
	else if(bShift)
		wVirtKey |= FSHIFT;
	else if(bAlt)
		wVirtKey |= FALT;

	return wVirtKey;
}

CString CAccelBase::GetAccelStr(WORD wVirtKey, WORD wKey)
{
	CString strAccel;
	strAccel = GetVirtKey(wVirtKey);
	if(!strAccel.IsEmpty())
		strAccel += _T("+");
	strAccel += GetKey(wKey);
	return strAccel;
}

CString CAccelBase::GetAccelStr(bool bCtrl, bool bShift, bool bAlt, WORD wKey)
{
	CString strAccel;
	if(bCtrl)
		strAccel += _T("Ctrl");
	if(bShift)
		strAccel += strAccel.IsEmpty() ? _T("Shift") : _T("+Shift");
	if(bAlt)
		strAccel += strAccel.IsEmpty() ? _T("Alt") : _T("+Alt");

	if(!strAccel.IsEmpty())
		strAccel += _T("+");
	strAccel += GetKey(wKey);

	return strAccel;
}
